ProxyExits
Overview
The ProxyExits extension defines the four ProxyExit objects that might be most commonly useful, for doorways, passages, paths, and archways, together with their associated SpecialTravelActions. This allows game authors an easy way to allow basic interaction with such items when they're mentioned in room descriptions without having to define a whole load of individual Door, Passage and PathPassage objects that wouldn't otherwise be needed.
For example, if a Room mentions a doorway, a passage and an archway, we can do somethingt like this:
hall: Room 'Hall'
"This large hall boasts an archway leading east and a long passage heading north. A door leads west. "
east = lounge
north = kitchen
west = study
archway = east // or archway = lounge
passageway = north // or passageway = kitchen
doorway = west // or doorway = study
;
Players will then get generic response to commands like X PASSAGE, GO THROUGH ARCH or ENTER DOOR without the game author needing to define individual Door or Passage objects for doors, passages and archways that are otherwise intended to be unremarkable.
To use the extension, we just need to include it in our build after the main library.
Principal Details
- Note that the properties to be defined on rooms using this extension all end in way: doorway, passageway, pathway. and archway. This is mainly to avoid name clashes that might arise from using the briefer names door, passsage, path and arch.
- The corresponding ProxyExit objects are called doorwayProxy, passagewayProxy, pathwayProxy and archwayProxy respectively. Game code can modify these objects if required, although the defaults provided may often work perfectly well.
- The vocab for these objects includes the appropriate nouns with and without -way (e.g. 'path' and 'pathway') together with a selection of adjectives that might be used in room descriptions to refer to such objects (e.g. 'broad' or 'narrow').
- These ProxyExit objects are effectively MultiLoc decorations that place themselves in every Room that defines the corresponding property, so that, for example,
doorwayProxywill be present in every room that defines thedoorwayproperty. - These ProxyExit objects will respond to EXAMINE with a bland response such as "Passages are just ordinary passages", which serves to acknowledge both their existence and their unremarkability. They will also respond to commands indicating an intention to travel via them, e.g. GO THROUGH DOOR, FOLLOW PATH, GO UP PASSSAGE, ENTER ARCHWAY (in which case what happens will depend on what's been defined on the corresponding Room property);
doorwayProxywill additionally respond to OPEN and CLOSED with 'Not needed in this case'. - These ProxyExit objects can coexist with 'real' objects of the same type in the same location (e.g. you can define a
doorwayproperty pointing in one direction and have a properDoorobject lying in other direction in the same Room), but then the parser will tend to favour the 'real' object. - The extension also defines the corresponding SpecialTravelActions
so that, for example, the command DOOR will trigger travel via whatever's defined on the
doorwayproperty of the current Room. - The
doorway,passageway,pathwayandarchwayproperties otherwise behave like any other non-directional travel properties and can be defined in just the same way.
If we don't like the defaults provided by these four objects, we can modify them to our own taste by overriding their vocab, desc and notImportantMsg properties just as we would for any other Decoration, plus the cannotOpenMsg and cannotCloseMsg properties on doorwayProxy. The aim in every case should be to give a bare, generic response to the player's command that acknowledges its legitimacy while discouraging any further interraction (apart from travellin via) these objects.
The example above suggested that we could define the related non-directional travel properties (such as doorway to be either the Room to which travelling via the ProxyExit (doorwayProxy or whatever) leads or to point to the directional exit property (e.g. west) the player would otherwise use to go there. The former is more direct, but the latter will be the better option whenever the directional exit property is defined as (or may later be changed to) anything other than a Room (i.e,. when we've defined a TravelConnector, method or string on that exit property). That way we can ensure that GO THROUGH DOOR (for example) will do just what WEST (or whatever the relevant direction is) would have done.
Handling Multiple Exits of the Same Type
A room description may often mention several exits of the same type leading from the same room, e.g.:
hall: Room 'Large Hall'
"This large hall has doorways leading off north, south, east and west. "
north = kitchen
south = drive
west = study
east = lounge
doorway = multiDoorMsg
;
Here it would be arbitrary to have GO THROUGH DOOR pick one of the directional exits arbitrarily. The best we can do is to point out to players that there are several doorways leading from the current room so they need to say which way they want to go. Rather than having to type this message each time, we can make use of the predefined Room properties multiDoorMsg, multiPassageMsg, multiPathMsg and multiArchMsg to do the job for us. If we don't like the wording this extension provides, we are, of course, free to override these properties to our taste.
A potentially knottier problem occurs when our room description mentions more than one exit of the same type but gives them slightly different descriptions, for example:
largeHall: Room 'Large Hall'
"You are in a large hall. A doorway leads north. A narrow passage leads south
while a wide one leads west, while the front door is just to the east. "
north = anotherRoom
doorway = anotherRoom
south tcMsg(kitchen, "You walk up the passage. ")
west = livingroom
east = frontDoor
passageway = ???
;
How should we define the passageway property here? If define it as either livingroom or south, players will think there's something wrong when they type GO THROUGH NARROW PASSAGE in the first case or FOLLOW WIDE PASSAGE in the second. But if we define passageway = multiPassageMsg players may be equally disgruntled to be told they need to choose which way to go when their command was already quite specific enough. One solution would be to reword the room description to avoid describing either passage, another would be to abandon the use of ProxyExits here and just define a pair of Passage objects to do the job, but there is a third option that avoids both these expedients, and that is to check whether the player's input included the word 'narrow' or the word 'wide' and choose the appopriate exit accordingly:
passageway
{
if(gToksInclude('narrow') && !gToksInclude('wide')) return south;
if(gToksInclude('wide') && !gToksInclude('narrow')) return west;
multiPassageMsg;
return nil;
}
Note that we provide for the player not mentioning either the wide passage or the narrow one (or specifying both at once) by falling back on the multiPassageMag if neither the token 'narrow' or the token 'wide' appears in their input without the other, but that otherwise our code will now choose the appropriate exit.
